from typing import Dict, List
from common.model import Song
from pydub import AudioSegment
import logging
import base64
import common.helper as helper


class AudioMediaConvertor:
    caches: Dict[str, str] = {}

    def get_file_path(self, key: str, songs: List[Song], mime: str, frame_rate: int, bitrate: str):
        """获取歌曲对应速率的文件路径"""

        for song in songs:
            if song.hashcode == key:
                # 不填写 mime 类型视为无需转换
                if self.is_same_audio(song, mime, frame_rate, bitrate):
                    print('直接返回')
                    return song.filepath

                # 优先取已经生成的
                cache_key = self.gen_key(key, mime, frame_rate, bitrate)
                if self.caches.__contains__(cache_key):
                    print("命中缓存")
                    return self.caches[cache_key]

                # 没有时开始手动生成
                newpath = self.convert_audio(song, mime, frame_rate, bitrate)
                if newpath is not None:
                    self.caches[cache_key] = newpath
                    print(f"newpath:{newpath}")
                    return newpath
        return None

    def convert_audio(self, song: Song, target_mime: str, frame_rate: int, bitrate: str):
        """音频文件格式转换"""

        # 码率等参数的格式转换
        target_path = helper.get_tempfile_path("." + target_mime)
        next_frame = song.frame_rate if frame_rate is None else frame_rate
        next_bit = str(song.bitrate / 1000) + \
            "k" if bitrate is None else bitrate

        # 根据不同文件类型生成 AudioSegment 对象
        try:
            if song.mime == "mp3":
                das = AudioSegment.from_mp3(
                    song.filepath).set_frame_rate(next_frame)
            elif song.mime == "wav":
                das = AudioSegment.from_wav(
                    song.filepath).set_frame_rate(next_frame)
            elif song.mime == "ogg":
                das = AudioSegment.from_ogg(
                    song.filepath).set_frame_rate(next_frame)
            else:
                das = AudioSegment.from_file(
                    song.filepath).set_frame_rate(next_frame)
        except:
            logging.error("AudioSegment 创建失败，请检查 ffmpeg 是否已安装")
            return None

        das.export(target_path, format=target_mime, bitrate=next_bit)
        return target_path

    def is_same_audio(self, song: Song, target_mime: str, frame_rate: int, bitrate: str):
        """判断音质是否相同"""

        if target_mime is None:
            return True
        same_frame = True if frame_rate is None or song.frame_rate == frame_rate else False
        origin_bit = str(song.bitrate / 1000) + "k"
        same_bit = True if bitrate is None or origin_bit == bitrate else False
        return song.mime == target_mime and same_frame and same_bit

    def gen_key(self, hasdcode: str, target_mime: str, frame_rate: int, bitrate: str):
        """生成缓存Key值"""

        frame_str = "0" if frame_rate is None else str(frame_rate)
        bitrate_str = "0k" if bitrate is None else bitrate
        return hasdcode + bitrate_str + frame_str + target_mime


class AlbumConvertor:
    caches: Dict[str, str] = {}

    def saveAlbumTemprary(self, song: Song):
        """临时保存专辑封面"""
        # 优先取已经生成的
        if self.caches.__contains__(song.hashcode):
            print("命中缓存")
            return self.caches[song.hashcode]

        # 没有时开始手动生成
        if song.picture is not None:
            target_path = helper.get_tempfile_path(".png")
            imgdata = base64.b64decode(song.picture)
            file = open(target_path, 'wb')
            file.write(imgdata)
            file.close()
            self.caches[song.hashcode] = target_path
            print(f"newpath:{target_path}")
            return target_path

        return None
